home *** CD-ROM | disk | FTP | other *** search
/ Deutsche Edition 1 / Deutsche Edition 1.iso / amok / 061-070 / amok63 / m2ced / txt.lha / Files.mod < prev    next >
Text File  |  1991-11-13  |  5KB  |  263 lines

  1. (**********************************************************************
  2.  
  3.     :Program.    Files.mod
  4.     :Contents.   Filebuffer
  5.     :Author.     Steffen Reith
  6.     :Address.    Hessenstr. 64, D-8700 Wuerzburg
  7.     :Phone.      None
  8.     :Copyright.  Shareware
  9.     :Language.   Modula-2
  10.     :Translator. M2Amiga A+L V3.32d
  11.     :History.    V1.0  7.Nov 1990
  12.     :Bugs.       Die Schreibmöglichkeiten dieses Modules sind nicht
  13.                  ausgetestet ==> EXTREME VORSICHT !!!!!
  14.  
  15. **********************************************************************)
  16. (*$ StackParms:=FALSE Volatile:=FALSE CaseChk:=FALSE *)
  17. (*$ StackChk:=FALSE RangeChk:=FALSE OverflowChk:=FALSE NilChk:=FALSE *)
  18. IMPLEMENTATION MODULE Files;
  19.  
  20. FROM Heap   IMPORT Allocate,Deallocate;
  21. FROM SYSTEM IMPORT ADR,ADDRESS,CAST;
  22.  
  23. IMPORT DosD;
  24. IMPORT DosL;
  25.  
  26. CONST BuffSize=02000H; (* 8k Buffer *)
  27.  
  28. TYPE FileDesBody=RECORD
  29.                   DosFile:DosD.FileHandlePtr;
  30.                   DosSize:LONGINT;
  31.                   DosPos:LONGINT;
  32.                   DosMode:FileModes;
  33.                   BufferPos:INTEGER; (* Buffer nicht grösser als 32 k *)
  34.                   Buffer:ARRAY[0..BuffSize-1] OF CHAR;
  35.                  END;
  36.      FileDes=POINTER TO FileDesBody;
  37.  
  38. PROCEDURE FillBuffer(File:FileDes);
  39.  
  40. VAR Dummy:LONGINT;
  41.  
  42. BEGIN
  43.  File^.BufferPos:=0;
  44.  Dummy:=DosL.Read(File^.DosFile,ADR(File^.Buffer),BuffSize);
  45.  File^.DosPos:=DosL.Seek(File^.DosFile,0,DosD.current)-Dummy
  46.  (* Mit diesem Trick scheint der Positionszeiger immer am Anfang zu stehen. *)
  47.  (* d.h. an der physikalischen Adresse, wo der Buffer beginnt.              *)
  48. END FillBuffer;
  49.  
  50. PROCEDURE Flush(File:FileDes);
  51.  
  52. VAR Dummy:LONGINT;
  53.  
  54. BEGIN
  55.  Dummy:=DosL.Write(File^.DosFile,ADR(File^.Buffer),File^.BufferPos);
  56.  File^.BufferPos:=0;
  57.  File^.DosPos:=DosL.Seek(File^.DosFile,0,DosD.current)
  58. END Flush;
  59.  
  60. PROCEDURE FileLength(VAR Name:ARRAY OF CHAR):LONGINT;
  61.  
  62. VAR IPtr:DosD.FileInfoBlockPtr;
  63.     LPtr:DosD.FileLockPtr;
  64.     Size:LONGINT;
  65.  
  66. BEGIN
  67.  
  68.  Allocate(IPtr,SIZE(DosD.FileInfoBlock));
  69.  IF IPtr=NIL THEN
  70.   RETURN 0
  71.  END;
  72.  
  73.  LPtr:=DosL.Lock(ADR(Name),SIZE(DosD.accessRead));
  74.  IF LPtr=NIL THEN RETURN 0 END;
  75.  IF NOT(DosL.Examine(LPtr,IPtr)) THEN
  76.   RETURN 0
  77.  END;
  78.  Size:=IPtr^.size;
  79.  DosL.UnLock(LPtr);
  80.  Deallocate(IPtr);
  81.  RETURN Size
  82. END FileLength;
  83.  
  84. PROCEDURE Open (VAR Name:ARRAY OF CHAR;Modus:FileModes):FileDes;
  85.  
  86. VAR File:FileDes;
  87.     Mode:INTEGER;
  88.     Dummy:LONGINT;
  89.  
  90. BEGIN
  91.  
  92.  Allocate(File,SIZE(FileDesBody));
  93.  IF File=NIL THEN
  94.   IOErr:=NoMem;
  95.   RETURN File
  96.  END;
  97.  
  98.  IF Modus=read THEN
  99.   Mode:=DosD.oldFile
  100.  ELSE
  101.   Mode:=DosD.newFile
  102.  END;
  103.  File^.DosMode:=Modus;
  104.  File^.DosFile:=DosL.Open(ADR(Name),Mode);
  105.  IF File^.DosFile=NIL THEN
  106.   Deallocate(File);
  107.   IOErr:=NoDosOpen;
  108.   RETURN NIL
  109.  END;
  110.  
  111.  File^.DosSize:=FileLength(Name);
  112.  
  113.  Dummy:=DosL.Seek(File^.DosFile,0,DosD.beginning);
  114.  
  115.  File^.BufferPos:=0;
  116.  IF Modus=read THEN
  117.   FillBuffer(File);
  118.  END;
  119.  
  120.  RETURN File
  121.  
  122. END Open;
  123.  
  124. PROCEDURE Close(File:FileDes);
  125.  
  126. BEGIN
  127.  IF File^.DosMode=write THEN Flush(File) END;
  128.  DosL.Close(File^.DosFile);
  129.  Deallocate(File)
  130. END Close;
  131.  
  132. PROCEDURE Read (File:FileDes;BuPtr:ADDRESS;Size:LONGINT);
  133.  
  134. BEGIN
  135.  LOOP
  136.   WHILE (Size>0) AND (File^.BufferPos<BuffSize)  DO
  137.    BuPtr^:=File^.Buffer[File^.BufferPos];
  138.    INC(File^.BufferPos);
  139.    INC(BuPtr);
  140.    DEC(Size);
  141.   END;
  142.   IF Size=0 THEN RETURN END;
  143.   FillBuffer(File)
  144.  END
  145. END Read;
  146.  
  147. PROCEDURE Write (File:FileDes;BuPtr:ADDRESS;Size:LONGINT);
  148.  
  149. VAR Dummy:LONGINT;
  150.  
  151. BEGIN
  152.  LOOP
  153.   WHILE (Size>0) AND (File^.BufferPos<BuffSize)  DO
  154.    File^.Buffer[File^.BufferPos]:=CAST(CHAR,BuPtr^);
  155.    INC(File^.BufferPos);
  156.    INC(BuPtr);
  157.    DEC(Size);
  158.   END;
  159.   IF Size=0 THEN RETURN END;
  160.   Flush(File)
  161.  END
  162. END Write;
  163.  
  164. PROCEDURE Read1 (File:FileDes):CHAR;
  165.  
  166. VAR ch:CHAR;
  167.  
  168. BEGIN
  169.  IF (File^.BufferPos>=BuffSize-1) THEN
  170.   FillBuffer(File)
  171.  END;
  172.  ch:=File^.Buffer[File^.BufferPos];
  173.  INC(File^.BufferPos);
  174.  RETURN (ch);
  175. END Read1;
  176.  
  177. PROCEDURE Write1 (File:FileDes;ch:CHAR);
  178.  
  179. BEGIN
  180.  IF (File^.BufferPos<=BuffSize-1) THEN
  181.   File^.Buffer[File^.BufferPos]:=ch
  182.  END;
  183.  INC(File^.BufferPos);
  184.  IF File^.BufferPos=BuffSize THEN
  185.   Flush(File)
  186.  END
  187. END Write1;
  188.  
  189. PROCEDURE Seek (File:FileDes;Pos:LONGINT;Loc:LocModes);
  190.  
  191. VAR Off:LONGINT;
  192.  
  193. PROCEDURE CheckBounds(VAR Pos:LONGINT):BOOLEAN;
  194.  
  195. BEGIN
  196.  IF (Pos>=0) AND (Pos<BuffSize) THEN
  197.   RETURN TRUE
  198.  ELSE
  199.   RETURN FALSE
  200.  END
  201. END CheckBounds;
  202.  
  203. PROCEDURE SetPtr(File:FileDes;Pos:LONGINT;Loc:LocModes);
  204.  
  205. VAR Dummy:LONGINT;
  206.  
  207. BEGIN
  208.  CASE Loc OF
  209.   |Front:Dummy:=DosL.Seek(File^.DosFile,Pos,DosD.beginning);
  210.   |Current:Dummy:=DosL.Seek(File^.DosFile,Pos,DosD.current);
  211.   |End:Dummy:=DosL.Seek(File^.DosFile,Pos,DosD.end);
  212.  END
  213. END SetPtr;
  214.  
  215. PROCEDURE Update(File:FileDes;Pos:LONGINT;Loc:LocModes);
  216.  
  217. BEGIN
  218.  IF File^.DosMode=read THEN
  219.   SetPtr(File,Pos,Loc);
  220.   FillBuffer(File)
  221.  ELSE
  222.   Flush(File);
  223.   SetPtr(File,Pos,Loc)
  224.  END
  225. END Update;
  226.  
  227.  
  228. BEGIN
  229.  CASE Loc OF
  230.   |Front:
  231.    Off:=Pos-File^.DosPos;
  232.    IF CheckBounds(Off) THEN
  233.     File^.BufferPos:=Off;
  234.    ELSE
  235.     Update(File,Pos,Loc)
  236.    END;
  237.   |Current:
  238.    Off:=File^.BufferPos+Pos;
  239.    IF CheckBounds(Off) THEN
  240.     File^.BufferPos:=Off;
  241.    ELSE
  242.     Update(File,Pos,Loc)
  243.    END;
  244.   |End:
  245.    Off:=(File^.DosSize-1)+Pos-File^.DosPos;
  246.    (* Diese Aktion macht bei write keinen Sinn Achtung Bug und Absturz *)
  247.    IF CheckBounds(Off) THEN
  248.     File^.BufferPos:=Off;
  249.    ELSE
  250.     Update(File,Pos,Loc)
  251.    END
  252.  END
  253. END Seek;
  254.  
  255. PROCEDURE WhereIAm(File:FileDes):LONGINT;
  256.  
  257. BEGIN
  258.  RETURN File^.DosPos+File^.BufferPos
  259. END WhereIAm;
  260.  
  261. BEGIN
  262. END Files.
  263.